package simplezap

import (
	"fmt"
	"io"
	"strings"
)

// Level 表示日志级别，从低到高依次为 Debug、Info、Warn、Error。
type Level int

const (
	LevelDebug Level = iota
	LevelInfo
	LevelWarn
	LevelError
)

func (l Level) String() string {
	switch l {
	case LevelDebug:
		return "DEBUG"
	case LevelInfo:
		return "INFO"
	case LevelWarn:
		return "WARN"
	case LevelError:
		return "ERROR"
	default:
		return "UNKNOWN"
	}
}

type Field struct {
	Key   string
	Value any
}

// Logger 第三版：在第二版基础上新增“最低级别”过滤能力。
type Logger struct {
	writer io.Writer
	level  Level
}

func New(w io.Writer) *Logger {
	return &Logger{writer: w, level: LevelInfo}
}

// SetLevel 允许教师/学员调整最低日志级别。
func (l *Logger) SetLevel(level Level) {
	l.level = level
}

func (l *Logger) Debug(message string, fields ...Field) error {
	return l.log(LevelDebug, message, fields)
}

func (l *Logger) Info(message string, fields ...Field) error {
	return l.log(LevelInfo, message, fields)
}

func (l *Logger) Warn(message string, fields ...Field) error {
	return l.log(LevelWarn, message, fields)
}

func (l *Logger) Error(message string, fields ...Field) error {
	return l.log(LevelError, message, fields)
}

func (l *Logger) log(level Level, message string, fields []Field) error {
	if l == nil {
		return fmt.Errorf("logger is nil")
	}
	if l.writer == nil {
		return fmt.Errorf("writer is nil")
	}
	if level < l.level {
		return nil
	}

	payload := message
	if len(fields) > 0 {
		payload = fmt.Sprintf("%s | %s", message, formatFields(fields))
	}

	if _, err := fmt.Fprintf(l.writer, "[%s] %s\n", level.String(), payload); err != nil {
		return fmt.Errorf("write log: %w", err)
	}
	return nil
}

func formatFields(fields []Field) string {
	parts := make([]string, 0, len(fields))
	for _, f := range fields {
		parts = append(parts, fmt.Sprintf("%s=%v", f.Key, f.Value))
	}
	return strings.Join(parts, ", ")
}
